Note that you have to put the CustomBehavior after a <module name="Search">. The reason for this is that if you're using relative time windows (which you will almost always be doing), putting the CustomBehavior after the <module name="Search"> will resolve those relative time ranges to absolute time ranges that you can use for math. This avoids the conundrum of trying to manually figure out what -4d@w+2h really means, programmatically. (This is one of those things that you would expect Splunk to have implemented, but it isn't. This is definitely a hacky approach to getting around the problem.) Obviously, though, you don't want to run your real search, because that would take forever. Searching for foo NOT foo is very quick, so it will resolve the time windows with only a brief delay (probably less than 1/3 second, your mileage may vary).
The code to put in your view:
<module name="TimeRangePicker"> <param name="default">Last 30 days</param> <param name="searchWhenChanged">True</param> <module name="Search" autoRun="True"> <param name="search">* | head 1</param> <module name="CustomBehavior"> <param name="customBehavior">GatherBins</param> <param name="requiresDispatch">True</param> <module name="HTML" layoutPanel="panel_row1_col1"> <param name="html"><![CDATA[<br /><p>Looking at $Bins$ bins of $Binsize$ each (alternatively, a span of $Span$).</p>]]></param> </module> </module> </module>Application.js Changes: The next step in the process is the actual code in your application.js. I think this should generally be readable without a full explanation. Essentially, I go through and based on the time span in question, I set up the number of bins. Then I do a similar calculation to decide what index to use. In my environment, I need to massage the raw data with an eval statement, so I added that as an extra field. In my actual dashboards, that shows up as a index=$ChooseIndex$ $ChooseEval$ | timechart MyField.</module>
if(typeof(Sideview)!="undefined"){ $(document).bind("allModulesInHierarchy",function(){ Sideview.utils.forEachModuleWithCustomBehavior("pickAppropriateColumns",function(b,a){ a.isReadyForContextPush = function(){ if(!this.RetrievedBinCount) return Splunk.Module.DEFER; if (this.getLoadState() < Splunk.util.moduleLoadStates.HAS_CONTEXT) return false; return true } a.onJobProgress = function() { var c=this.getContext(); var d=c.get("search").job; this.Bins = 0; this.Binsize = ""; var latest = new Date(d._latestTime); var earliest = new Date(d._earliestTime); var earliestEpoch = earliest.valueOf() / 1000; var latestEpoch = latest.valueOf() / 1000; if(latest.valueOf() == 0){ latest = new Date(); } var Difference = (latest.valueOf() - earliest.valueOf()) / 1000; this.RetrievedBinCount = true; this.FractionOfMonth = Difference / (30*24*60*60); this.Difference = Difference; if(Difference > (730*24*60*60)){ //More than 730 days -- summarize four days this.Bins = parseInt(Difference / (96*60*60))+2; this.Binsize = "Four Days"; this.Span = "4d"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else if(Difference > (450*24*60*60)){ //More than 450 days -- summarize two days this.Bins = parseInt(Difference / (48*60*60))+2; this.Binsize = "Two Days"; this.Span = "2d"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else if(Difference > (150*24*60*60)){ //More than 150 days -- summarize daily this.Bins = parseInt(Difference / (24*60*60))+2; this.Binsize = "One Day"; this.Span = "1d"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else if(Difference > (100*24*60*60)){ //More than 100 days -- summarize 12 hourly this.Bins = parseInt(Difference / (12*60*60))+2; this.Binsize = "12 Hours"; this.Span = "12h"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else if(Difference > (50*24*60*60)){ //More than 50 days -- summarize 8 hourly this.Bins = parseInt(Difference / (8*60*60))+2; this.Binsize = "8 Hours"; this.Span = "8h"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else if(Difference > (14*24*60*60)){ //More than 14 days -- summarize 4 hourly this.Bins = parseInt(Difference / (4*60*60))+2; this.Binsize = "4 Hours"; this.Span = "4h"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else if(Difference > (6*24*60*60)){ //More than 6 days -- summarize hourly this.Bins = parseInt(Difference / (60*60))+2; this.Binsize = "One Hour"; this.Span = "1h"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else if(Difference > (2*24*60*60)){ //More than 2 days -- summarize half-hourly this.Bins = parseInt(Difference / (30*60))+2; this.Binsize = "30 Minutes"; this.Span = "30m"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) }else{ //Less than 2 days -- summarize to 10 minutes this.Bins = parseInt(Difference / (10*60))+2; this.Binsize = "10 Minutes"; this.Span = "10m"; this.AbsoluteEarliest = earliestEpoch - (earliestEpoch % (24*3600)) this.AbsoluteLatest = latestEpoch + (24*3600 - (latestEpoch % (24*3600))) } // Now let's do the index... if(Difference > (150*24*60*60)){ this.ChooseIndex = "my_summary_daily" this.ChooseEval = "" }else if(Difference > (6*24*60*60)){ this.ChooseIndex = "my_summary_hourly" this.ChooseEval = "" }else{ this.ChooseIndex = "rtbbid" this.ChooseEval = " | eval MyField = MyField * 300" } this.pushContextToChildren(); } a.getModifiedContext=function(){ var context=this.getContext(); context.set("Bins", this.Bins); context.set("Binsize", this.Binsize); context.set("Span", this.Span); context.set("AbsoluteEarliest", this.AbsoluteEarliest); context.set("AbsoluteLatest", this.AbsoluteLatest); context.set("ChooseIndex", this.ChooseIndex); context.set("ChooseEval", this.ChooseEval); context.set("SpendGraphType", this.SpendGraphType); context.set("FractionOfMonth", this.FractionOfMonth); context.set("TimeWindowInSec", this.Difference); context.set("ChooseDailyAppend", this.ChooseDailyAppend); return context } }) })Having Issues?: Let me know in the comments, or contact me from the link above.}